package cn.wolfcode.wolf2w.interceptor;

import cn.wolfcode.wolf2w.annotation.RequireLogin;
import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.redis.service.IUserInfRedisService;
import cn.wolfcode.wolf2w.util.JsonResult;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 用户登录拦截器
 */
public class CheckLoginInterceptor implements HandlerInterceptor {

    @Autowired
    IUserInfRedisService redisService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        /**
         *  1:spring容器启动是会解析所有@RequestMapping 标签
         *  将解析到所有请求映射方法相关信息(路径, 方法名, 方法参数 注解...)
         *  封装成HandlerMethod对象
         *  2: 将步骤1得到所有请求映射方法对象, 封装到一个类似map数据
         *    key值是映射路径  value值就是HandlerMethod对象
         *
         *    Map<String, HandlerMethod> map
         *
         *    key                   value
         *    /users/currentUser    currentUser映射方法对应:HandlerMethod对象
         *    /users/login          login映射方法对应:HandlerMethod对象
         *
         *  3:当浏览器发起请求时, springmvc前端控制器会解析请求得到路径
         *    http://localhost:8080/users/currentUser
         *
         *    url(key) : /users/currentUser
         *    HandlerMethod value = map.get("/users/currentUser")
         *
         *   通过一系列操作得到 value对象, 然后传入到interceptor拦截器
         *    preHandler方法中(作为参数传入)
         */

        //解决跨域访问问题
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        //获取所有controller中的方法
        HandlerMethod hm = (HandlerMethod) handler;

        String token = request.getHeader("token");
        UserInfo user = redisService.getUserByToken(token);
        //未登录
        if (hm.hasMethodAnnotation(RequireLogin.class)) {
            if (user == null) {
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().write(JSON.toJSONString(JsonResult.noLogin()));
                return false;
            }
        }
        return true;
    }
}
